﻿#ifndef _PACKAGE_UTIL_H_
#define _PACKAGE_UTIL_H_

// max package size is 512KB
#define MAX_PACKAGE_SIZE 524288

namespace Common
{
	enum ErrorType
	{
		NoError = 0,
		ModelError,
		CtrlError,
		EventError,
		JsonTreeError,
		DataFormatError,
		LogicError,
	};

	enum DataFormat
	{
		Binary = 0,
		Json,
		GZipJson,
		ZlibJson,
	};

	enum DataType
	{
		NormalData,
		BroadcastData,
		MulticastData,
		DelayData,
		DelayUpData,
		DelayBroadcastData,
		DelayMulticastData,
		FinData,
		EmptyData,
	};

	enum ServerType
	{
		LoginServerType,
		GameServerType,
	};

	struct PackageHead
	{
		unsigned char protocol;
		unsigned char version;
		unsigned char game;
		unsigned char server_type;
		unsigned int length;
		unsigned int player_id;
		unsigned short server;
		unsigned char append_data;
		unsigned char multi_data;
	};

	struct DataHead
	{
		unsigned int character_id;
		unsigned short length;
		unsigned short format;
	};

	struct MulticastHead
	{
		int player_num;
	};

	struct DelayHead
	{
		unsigned int delay_ms;
	};
}

class PackageUtil
{
public:

	static struct Common::PackageHead *GetPackageHead(char *buf)
	{
		return (struct Common::PackageHead *)buf;
	};

	static struct Common::DataHead *GetFirstDataHead(char *buf)
	{
		return (struct Common::DataHead *)(buf + sizeof(struct Common::PackageHead));
	};

	static int GetPackageLen(char *buf)
	{
		struct Common::PackageHead *p_head = GetPackageHead(buf);
		return sizeof(struct Common::PackageHead) + p_head->length;
	}

	static int GetFirstPackageLen(char *buf)
	{
		struct Common::DataHead *p_head = GetFirstDataHead(buf);
		return sizeof(struct Common::PackageHead) + sizeof(struct Common::DataHead) + p_head->length * sizeof(int);
	};

	static struct Common::DelayHead *GetDelayHead(char *buf)
	{
		return (struct Common::DelayHead *)(buf + GetFirstPackageLen(buf));
	};

	static struct Common::MulticastHead *GetMulticastHead(char *buf)
	{
		return (struct Common::MulticastHead *)(buf + GetFirstPackageLen(buf));
	};

	static struct Common::DelayHead *GetDelayMulticastHead(char *buf)
	{
		struct Common::MulticastHead *p_multicast_head = GetMulticastHead(buf);
		return (struct Common::DelayHead *)((char *)p_multicast_head +
            sizeof(struct Common::MulticastHead) + p_multicast_head->player_num * sizeof(int));
	}

	static Common::PackageHead *GetNextPackageHead(Common::PackageHead *p_package_head)
	{
		return (Common::PackageHead *)((char *)p_package_head + sizeof(struct Common::PackageHead) + p_package_head->length);
	}
};

#endif
